package part18封装数据库工具类;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.sun.rowset.CachedRowSetImpl;

/**
 * JDBC数据库封装-工具类
 * @author Administrator
 *
 */
public class DBUtil {
	// 静态常量
	private static final String DRIVER= "com.mysql.jdbc.Driver";
	private static final String USER= "root";
	private static final String PASSWORD= "root";
	private static final String URL= "jdbc:mysql://127.0.0.1:3306/jja1912_1?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&serverTimezone=GMT&useAffectedRows=true";
	
	/**
	 * 获取数据库连接对象
	 * @return Connection
	 */
	private static Connection getConnection() {
		Connection conn = null;
		
		try {
			// 加载驱动到JVM中
			Class.forName(DRIVER);
			// 获取连接对象
			conn = DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}
	/**
	 * 关闭数据库资源
	 * @param resultSet 结果集对象
	 * @param pstat	预编译语句对象
	 * @param conn  连接对象
	 */
	public static void closeAll(ResultSet resultSet, PreparedStatement pstat, Connection conn) {
		try {
			if (resultSet != null) {
				resultSet.close();
			}
			if (pstat != null) {
				pstat.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 查询
	 * 查询所有 select * from 表
	 * 查询单个  select * from 表 where 字段 = ?
	 * 查询用户名和密码    select * from 表 where 字段 = ? and 字段2 = ?
	 * 
	 * 问题1：sql文的参数个数不确定，可能0个，可能是1个，可以多个...
	 * 解决：使用可变参数 存储0-N个参数
	 * 问题2：结果集不能关闭后返回，利用缓存结果集解决
	 * @param sql
	 * @return
	 */
	public static ResultSet doQuery(String sql,Object... params) {
		
		Connection conn = null;
		PreparedStatement pstat = null;
		ResultSet resultSet = null;
		// 缓存结果集
		CachedRowSetImpl  rowset = null;
		try {
			// 1获取连接对象
			conn = getConnection();
			
			// 2创建预编译语句对象
			pstat = conn.prepareStatement(sql);
			// 3对占位符赋值
			for (int i = 0; i < params.length; i++) {
				pstat.setObject(i+1, params[i]);
			}
			// 执行SQL
			resultSet = pstat.executeQuery();
			
			// 实例化缓存结果集
			rowset = new CachedRowSetImpl();
			// 将结果集的数据 存储到 缓存结果集中
			rowset.populate(resultSet);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 调用关闭数据库资源的方法
			closeAll(resultSet, pstat, conn);
		}
		return rowset; // 返回是 缓存结果集  rowset是ResultSet的子类。
	}
	/**
	 * 更新（insert update delete）
	 * insert into employee values(null,?,?)
	 * delete from employee where 字段  = ?
	 */
	public static int doUpdate(String sql, Object...params) {
		Connection conn = null;
		PreparedStatement pstat = null;
		int n = 0; // 影响行数
		try {
			// 获取连接对象
			conn = getConnection();
			// 获取预编译语句对象
			pstat = conn.prepareStatement(sql);
			// 对占位符赋值
			for (int i = 0; i < params.length; i++) {
				pstat.setObject(i+1, params[i]);
			}
			
			// 执行SQL
			n = pstat.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 调用关闭数据库的方法
			closeAll(null, pstat, conn);
		}
		return n;
	}
}
